import AVFoundation
import UIKit

class YCCameraManualController {
    
    // MARK: - Properties
    private weak var device: AVCaptureDevice?
    
    // 当前值
    private(set) var currentISO: Float = 0
    private(set) var currentShutterSpeed: CMTime = .zero
    private(set) var currentWhiteBalance: Float = 0
    
    // 值范围
    private(set) var minISO: Float = 0
    private(set) var maxISO: Float = 0
    private(set) var minExposureDuration: CMTime = .zero
    private(set) var maxExposureDuration: CMTime = .zero
    
    // MARK: - Initialization
    init(device: AVCaptureDevice?) {
        self.device = device
        setupRanges()
    }
    
    // MARK: - Setup
    private func setupRanges() {
        guard let device = device else { return }
        
        // 设置 ISO 范围
        minISO = device.activeFormat.minISO
        maxISO = device.activeFormat.maxISO
        
        // 设置快门速度范围
        minExposureDuration = device.activeFormat.minExposureDuration
        maxExposureDuration = device.activeFormat.maxExposureDuration
        
        // 获取当前值
        currentISO = device.iso
        currentShutterSpeed = device.exposureDuration
        currentWhiteBalance = device.deviceWhiteBalanceGains.blueGain
    }
    
    // MARK: - Manual Controls
    
    /// 设置 ISO 值
    /// - Parameter value: 0.0 - 1.0 之间的值，会被映射到设备支持的 ISO 范围
    func setISO(_ value: Float) {
        guard let device = device else { return }
        
        // 将 0-1 的值映射到设备支持的 ISO 范围
        let iso = value * (maxISO - minISO) + minISO
        
        do {
            try device.lockForConfiguration()
            
            // 设置手动曝光模式
            if device.isExposureModeSupported(.custom) {
                device.exposureMode = .custom
                device.setExposureModeCustom(duration: device.exposureDuration, iso: iso) { _ in }
            }
            
            device.unlockForConfiguration()
            currentISO = iso
            
        } catch {
            print("设置 ISO 失败: \(error)")
        }
    }
    
    /// 设置快门速度
    /// - Parameter value: 0.0 - 1.0 之间的值，会被映射到设备支持的快门速度范围
    func setShutterSpeed(_ value: Float) {
        guard let device = device else { return }
        
        // 注意：minExposureDuration 和 maxExposureDuration 的关系与直觉相反
        // minExposureDuration 对应最短曝光时间（快门速度最快）
        // maxExposureDuration 对应最长曝光时间（快门速度最慢）
        
        // 获取秒数范围
        let minSeconds = Float64(minExposureDuration.value) / Float64(minExposureDuration.timescale)
        let maxSeconds = Float64(maxExposureDuration.value) / Float64(maxExposureDuration.timescale)
        
        // 打印调试信息
        print("设备支持的快门速度范围: \(1.0/maxSeconds)秒 - \(1.0/minSeconds)秒")
        
        // 使用指数映射更合理地分配快门速度范围
        // 对数映射：value 0->1 映射到 log(minSeconds)->log(maxSeconds)
        let logMinSec = log10(minSeconds)
        let logMaxSec = log10(maxSeconds)
        
        // 计算目标秒数（对数空间中的线性插值）
        let logSeconds = logMinSec + (logMaxSec - logMinSec) * Double(value)
        let seconds = pow(10.0, logSeconds)
        
        // 确保值在有效范围内
        let safeSeconds = min(max(seconds, minSeconds), maxSeconds)
        
        // 创建时间结构
        let duration = CMTimeMakeWithSeconds(safeSeconds, preferredTimescale: 1000000)
        
        // 显示当前设置的快门速度
        let shutterSpeed = 1.0 / safeSeconds
        print("设置快门速度为: \(shutterSpeed >= 1.0 ? String(format: "1/%.0f", shutterSpeed) : String(format: "%.2f", 1.0/shutterSpeed))秒")
        
        do {
            try device.lockForConfiguration()
            
            if device.isExposureModeSupported(.custom) {
                device.exposureMode = .custom
                
                // 设置自定义曝光模式，time参数是实际应用的曝光时间
                device.setExposureModeCustom(duration: duration, iso: device.iso) { (time) in
                    // 如果设备无法设置精确的曝光时间，它会返回实际应用的时间
                    // 使用CMTimeCompare正确比较两个CMTime值
                    if CMTimeCompare(time, duration) != 0 {
                        let actualSeconds = CMTimeGetSeconds(time)
                        let actualShutterSpeed = 1.0 / actualSeconds
                        print("实际应用的快门速度: \(actualShutterSpeed >= 1.0 ? String(format: "1/%.0f", actualShutterSpeed) : String(format: "%.2f", 1.0/actualShutterSpeed))秒")
                    }
                }
            } else {
                print("设备不支持自定义曝光模式")
            }
            
            device.unlockForConfiguration()
            currentShutterSpeed = duration
            
        } catch {
            print("设置快门速度失败: \(error.localizedDescription)")
        }
    }
    
    /// 设置白平衡
    /// - Parameters:
    ///   - temperature: 0.0 - 1.0 色温值
    ///   - tint: -1.0 - 1.0 色调值
    func setWhiteBalance(temperature: Float, tint: Float = 0) {
        guard let device = device else { return }
        
        do {
            try device.lockForConfiguration()
            
            // 确保设备支持锁定白平衡模式
            if device.isWhiteBalanceModeSupported(.locked) {
                device.whiteBalanceMode = .locked
                
                // 将输入值映射到设备支持的色温范围(2500K-7500K)
                let kelvin: Float = 2500 + (temperature * 5000)
                
                // 创建温度和色调值
                let temperatureAndTintValues = AVCaptureDevice.WhiteBalanceTemperatureAndTintValues(
                    temperature: kelvin,
                    tint: tint * 150) // 色调范围通常为-150到+150
                
                // 直接使用系统API获取白平衡增益，避免自定义计算错误
                do {
                    let gains = try device.deviceWhiteBalanceGains(for: temperatureAndTintValues)
                    
                    // 确保增益值在有效范围内
                    let normalizedGains = self.normalizeGains(gains: gains, device: device)
                    
                    // 应用白平衡增益
                    device.setWhiteBalanceModeLocked(with: normalizedGains)
                    currentWhiteBalance = temperature
                } catch {
                    print("计算白平衡增益失败: \(error.localizedDescription)")
                    // 如果转换失败，可以尝试使用之前的方法作为备用
                    var gains = AVCaptureDevice.WhiteBalanceGains()
                    gains.redGain = 1.0
                    gains.greenGain = 1.0
                    gains.blueGain = 1.0
                    device.setWhiteBalanceModeLocked(with: gains)
                }
            } else {
                print("设备不支持锁定白平衡模式")
            }
            
            device.unlockForConfiguration()
            
        } catch {
            print("设置白平衡失败，无法锁定设备配置: \(error.localizedDescription)")
        }
    }
    
    /// 规范化白平衡增益值
    private func normalizeGains(gains: AVCaptureDevice.WhiteBalanceGains, device: AVCaptureDevice) -> AVCaptureDevice.WhiteBalanceGains {
        var normalizedGains = gains
        
        // 获取设备支持的最大增益值
        let maxGain = device.maxWhiteBalanceGain
        
        // 确保所有增益值在允许的范围内(1.0-maxGain)
        normalizedGains.redGain = min(max(gains.redGain, 1.0), maxGain)
        normalizedGains.greenGain = min(max(gains.greenGain, 1.0), maxGain)
        normalizedGains.blueGain = min(max(gains.blueGain, 1.0), maxGain)
        
        return normalizedGains
    }
    
    /// 重置所有手动设置到自动模式
    func resetToAutoMode() {
        guard let device = device else { return }
        
        do {
            try device.lockForConfiguration()
            
            // 重置曝光模式
            if device.isExposureModeSupported(.continuousAutoExposure) {
                device.exposureMode = .continuousAutoExposure
            }
            
            // 重置白平衡模式
            if device.isWhiteBalanceModeSupported(.continuousAutoWhiteBalance) {
                device.whiteBalanceMode = .continuousAutoWhiteBalance
            }
            
            device.unlockForConfiguration()
            
        } catch {
            print("重置到自动模式失败: \(error)")
        }
    }
} 
